﻿using System.AutoUpdate.Tools;
using System.ComponentModel;
using System.Net;
using System.Threading;

namespace System.AutoUpdate.Core.Sources
{
    /// <summary>
    /// Provides base class for web source (updates on a HTTP server)
    /// </summary>
    public abstract class WebSource : SimpleSource
    {
        private readonly CustomWebClient _client;

        protected WebSource ()
        {
            _client = new CustomWebClient(180 * 1000);
            
            _client.DownloadFileCompleted += ClientOnDownloadFileCompleted;
            _client.DownloadProgressChanged += ClientOnDownloadProgressChanged;
        }

        private void ClientOnDownloadProgressChanged (object sender, DownloadProgressChangedEventArgs downloadProgressChangedEventArgs)
        {
            TransferEvent (Core.TransferEvent.Progress, this, new TransferEventArgs
                                                              {
                                                                  TransferredBytes = downloadProgressChangedEventArgs.BytesReceived
                                                              });
        }

        private void ClientOnDownloadFileCompleted (object sender, AsyncCompletedEventArgs asyncCompletedEventArgs)
        {
            TransferEvent (Core.TransferEvent.Completed, this, new TransferEventArgs
                                                               {
                                                                   Exception = asyncCompletedEventArgs.Error
                                                               });
        }

        /// <summary>
        /// Downloads file as a string
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        protected string DownloadString (string uri)
        {
            try
            {
                Thread.Sleep(1000);

                return _client.DownloadString (uri);
            }
            catch (Exception ex)
            {
                return String.Empty;
            }
        }

        /// <summary>
        /// Returns size of HTML document or file on uri
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        protected long GetFileSize (string uri)
        {
            try
            {
                Thread.Sleep (1000);

                _client.OpenRead(uri);

                return Convert.ToInt64(_client.ResponseHeaders["Content-Length"]);
            }
            catch (Exception ex)
            {
                return 0;
            }
        }

        /// <summary>
        /// Downloads file async
        /// </summary>
        /// <param name="fileUri"></param>
        /// <param name="localFolder"></param>
        protected void DownloadFile (string fileUri, string localFolder)
        {
            TransferEvent (Core.TransferEvent.Started, this, new TransferEventArgs ());

            _client.DownloadFileAsync(new Uri (fileUri), "");
        }
    }
}
